/*
 * @Description: 排列规则面板
 * @Author: Rfan
 * @Date: 2022-10-26 18:44:10
 * @LastEditTime: 2022-10-31 17:39:07
 */

import { Key, useCallback, useEffect, useState } from 'react';
import { Button, Form, Input, Transfer, Typography } from 'antd';
import classNames from 'classnames/bind';
import update from 'immutability-helper';
import { DndProvider } from 'react-dnd';
import { HTML5Backend } from 'react-dnd-html5-backend';
import { fetchMetadata } from '@/api/metadata';
import { useAutoIncreaseContext } from '../contexts/AutoIncreaseContext';
import { QUERY_METADATA_SORT } from '@/view/system/Metadata/constants';
import TransferSelectItem from './TransferSelectItem';
import type { ICoordinate } from '@/interfaces/global';
import styles from '../styles/panes.module.scss';

const cx = classNames.bind(styles);

const { Text } = Typography;

/**
 * @description: 自增字段面板
 */
const IncreasePane = () => {
  const { selectAT, selectLevel, commonRule, saveGroupSortRuleFunc } = useAutoIncreaseContext();
  const [form] = Form.useForm();

  // 元数据列表
  const [fieldList, setFieldList] = useState([]);
  // 已选择字段列表
  const [selectFieldList, setSelectFieldList] = useState([]);
  // 穿梭框选中的项目key集合（穿梭框右侧）
  const [targetKeys, setTargetKeys] = useState<string[]>([]);
  // 穿梭框右侧渲染的项目列表，用于右侧项目渲染及提交提交
  const [targetItems, setTargetItems] = useState([]);
  // 选中项目的key集合
  const [selectedKeys, setSelectedKeys] = useState([]);
  // 保存按钮是否可点击标志
  const [saveFlag, setSaveFlag] = useState<boolean>(false);

  useEffect(() => {
    const level = selectLevel.level;
    if (level) {
      const coordinate: ICoordinate = {
        atCode: selectAT.atCode,
        atType: selectAT.atType,
        level
      };

      const fieldQuery = {
        metadataFieldType: QUERY_METADATA_SORT,
        coordinate
      };
      // 获取所有元数据
      fetchMetadata(fieldQuery).then((res) => {
        setFieldList(
          res.data.map((item: any) => {
            item.key = item.id;
            item.sortType = item.sortType || 0;
            return item;
          })
        );
      });
    }
  }, [selectLevel]);

  useEffect(() => {
    if (commonRule?.sortFieldResultList && commonRule.sortFieldResultList.length > 0) {
      setSelectFieldList(commonRule.sortFieldResultList);
    }
    if (commonRule?.serialLength) {
      form.setFieldsValue({ serialLength: commonRule.serialLength });
    }
  }, [commonRule]);

  useEffect(() => {
    setTargetKeys(selectFieldList.map((item: any) => item.fieldId));
    setTargetItems(
      selectFieldList.map((item: any) => ({
        ...item,
        key: item.fieldId
      }))
    );
  }, [selectFieldList]);

  /**
   * @description: 提交表单，触发表单提交事件
   */
  const submitFunc = () => {
    console.log('submit', form);
    form.submit();
  };
  /**
   * @description: 保存自增字段
   * @param {any} values
   */
  const onFinish = (values: any) => {
    const sortFieldList = targetItems.map((item: any, idx: number) => ({
      sortType: item.sortType || 0,
      sortNo: idx,
      fieldId: item.id || item.fieldId
    }));
    console.log('form finish', values, targetItems, sortFieldList);
    saveGroupSortRuleFunc({ ...commonRule, ...values, sortFieldList });
  };

  /**
   * @description: 选项在两栏之间转移时的回调函数,direction='right' 时为增加，direction='left' 时为删除
   * @param {any} nextTargetKeys 右侧框的key集合
   */
  const onChange = (nextTargetKeys: any) => {
    setSaveFlag(true);
    setTargetKeys(nextTargetKeys);
    setTargetItems(
      nextTargetKeys.reverse().map((key: number | string) => {
        const fieldItem = fieldList.find((item) => item.id === key) || {};
        const listItem = selectFieldList.find((lItem: any) => lItem.fieldId === key) || {};
        return { ...fieldItem, ...listItem };
      })
    );
  };

  /**
   * @description: 选中项发生改变时的回调函数，用于项目选中的展示，设置为 单选
   * @param {function} sourceSelectedKeys 左侧选中
   * @param {function} targetSelectedKeys 右侧选中
   */
  const onSelectChange = (sourceSelectedKeys: Key[], targetSelectedKeys: Key[]) => {
    setSelectedKeys([...sourceSelectedKeys, ...targetSelectedKeys]);
  };

  /**
   * @description: 拖拽选中的条目触发，在此更新list
   */
  const moveSelect = useCallback((dragIndex: number, hoverIndex: number) => {
    console.log('moveSelect', dragIndex, hoverIndex);
    setTargetItems((state: any) =>
      update(state, {
        $splice: [
          [dragIndex, 1],
          [hoverIndex, 0, state[dragIndex]]
        ]
      })
    );
  }, []);

  /**
   * @description: 生成可拖拽列表
   */
  const renderSelect = useCallback((selectItem: any, listProps: any, index: number, onChange) => {
    return (
      <TransferSelectItem
        {...listProps}
        key={selectItem.key}
        index={index}
        item={selectItem}
        onChange={onChange}
        moveSelect={moveSelect}
        type={2}
      />
    );
  }, []);

  return (
    <div className={`auto-pane ${cx('filing-pane')}`}>
      <div className={cx('filing-header')}>
        <div className={cx('title')}>{selectLevel.levelName}-序号基本设置</div>
        <div className={cx('operate')}>
          <Button disabled={!saveFlag} onClick={submitFunc}>
            保存
          </Button>
        </div>
      </div>
      <div className={cx('container')}>
        <Form preserve={false} form={form} size="small" onFinish={onFinish}>
          <Typography>
            <pre className={cx('setting-info')}>
              <Form.Item label="对于项目档案"></Form.Item>
              <Form.Item label="自增字段">
                <Text type="success" underline strong>
                  {selectLevel.levelName}
                </Text>
                中固定必须使用的自增字段为
                <Text type="success" underline strong>
                  序号
                </Text>{' '}
              </Form.Item>
              <Form.Item label="默认长度" extra="默认长度的允许设置范围为1~9，且必须设置" required>
                自增时默认长度为{'  '}
                <Form.Item
                  name="serialLength"
                  noStyle
                  rules={[{ required: true, message: '请输入默认长度' }]}
                >
                  <Input
                    style={{ width: 65 }}
                    onChange={() => {
                      setSaveFlag(true);
                    }}
                  />
                </Form.Item>
                <span>
                  {'  '}
                  位，不足以“0”补（如设置值为{' '}
                  <Text type="success" underline strong>
                    3
                  </Text>{' '}
                  则初始值为001 ）
                </span>
              </Form.Item>
            </pre>
          </Typography>
          <Form.Item
            wrapperCol={{ span: 20 }}
            labelCol={{ span: 24 }}
            label={
              <>
                <Typography.Text type="success" strong>
                  {selectLevel.levelName}-序号
                </Typography.Text>{' '}
                <Typography.Text strong> 排列设置</Typography.Text>
              </>
            }
          >
            从字段列表中选择后，点击双箭头按钮，可以设置或取消待选字段。
            <Transfer
              dataSource={fieldList}
              titles={['待选排序字段', '已选排序字段']}
              listStyle={{
                width: '50%',
                height: 320
              }}
              targetKeys={targetKeys}
              selectedKeys={selectedKeys}
              onChange={onChange}
              onSelectChange={onSelectChange}
              render={(item) => ({ label: item.field_desc, value: item.id })}
              showSelectAll={false}
            >
              {(listProps) => {
                if (listProps.direction === 'right') {
                  return (
                    <DndProvider backend={HTML5Backend}>
                      <div className="ant-transfer-list-content">
                        {targetItems.map((item: any, idx: number) =>
                          renderSelect(item, listProps, idx, setSaveFlag)
                        )}
                      </div>
                    </DndProvider>
                  );
                }
              }}
            </Transfer>
          </Form.Item>
        </Form>
      </div>
    </div>
  );
};

export default IncreasePane;
